home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 002 / make / macro.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  4KB  |  171 lines

  1. #include <stdio.h>
  2. #include "make.h"
  3.  
  4. /*
  5.  * Macro processing
  6.  */
  7.  
  8. /*
  9.  * Perform macro substitution from 'orig' to 'dest'.
  10.  * Return number of macro substitutions made.
  11.  * A macro reference is in one of two forms:
  12.  *        <MACCHAR>(macro-name)
  13.  *      or    <MACCHAR><single-character>
  14.  *
  15.  * "<MACCHAR><MACCHAR>" expands to a single '<MACCHAR>'
  16.  */
  17.  
  18. mexpand (orig, dest, destsiz, macchar)
  19. char *orig;
  20. char *dest;
  21. int destsiz;
  22. char macchar;
  23. {
  24.     register char *s;
  25.     register char *d;
  26.     auto char mname[STRSIZ];
  27.     register int di;
  28.     register int count;
  29.     /* MACRO *m; */
  30.  
  31.     DBUG_ENTER ("mexpand");
  32.     di = count = 0;
  33.     for (s = orig; *s;) {
  34.     if (*s == macchar) {
  35.         if (*++s == macchar) {
  36.         if (di < destsiz - 1) {
  37.             dest[di++] = *s++;
  38.         }
  39.         continue;
  40.         }
  41.         if (!*s) {
  42.         break;
  43.         }
  44.         d = mname;
  45.         if (*s != '(') {
  46.         *d++ = *s++;
  47.         } else {
  48.         for (++s; *s && *s != ')';) {
  49.             *d++ = *s++;
  50.         }
  51.         if (*s != ')') {
  52.             puts ("Missed matching ')'");
  53.         } else {
  54.             ++s;
  55.         }
  56.         }
  57.         *d = 0;
  58.         if ((d = gmacro (mname)) == NULL) {
  59. #ifdef VAXVMS || MSDOS
  60.         /* Preserve old behavior.  Someone else can remove it */
  61.         /* if desired.  The prefered behavior, at least for */
  62.         /* unix types, is to simply ignore undefined macros. */
  63.         /* Fred Fish, 28-Nov-85 */
  64.         fputs ("Undefined macro: ", stderr);
  65.         fputs (mname, stderr);
  66.         fputc ('\n', stderr);
  67. #endif    
  68.         } else {
  69.         while (*d && di < (destsiz - 1)) {
  70.             dest[di++] = *d++;
  71.         }
  72.         ++count;
  73.         }
  74.     } else if (di < destsiz - 1) {
  75.         dest[di++] = *s++;
  76.     }
  77.     }
  78.     dest[di] = 0;
  79.     DBUG_3 ("mac", "expanded %d macros", count);
  80.     DBUG_RETURN (count);
  81. }
  82.  
  83. /*
  84.  * Define a macro.
  85.  * Give the macro called 'name' the string expansion 'def'.
  86.  * Old macro-names are superseded, NOT replaced.
  87.  */
  88.  
  89. void defmac (name, def)
  90. char *name;
  91. char *def;
  92. {
  93.     register MACRO *m;
  94.  
  95.     DBUG_ENTER ("defmac");
  96.     DBUG_4 ("mdef", "define macro '%s' to be '%s'", name, def);
  97.     if ((m = (MACRO *) Calloc (1, sizeof (MACRO))) == (MACRO *) NULL) {
  98.     allerr ();
  99.     }
  100.     if ((m -> mname = (char *) Calloc (1, strlen (name) + 1)) == NULL) {
  101.     allerr ();
  102.     }
  103.     if ((m -> mvalue = (char *) Calloc (1, strlen (def) + 1)) == NULL) {
  104.     allerr ();
  105.     }
  106.     strcpy (m -> mname, name);
  107.     strcpy (m -> mvalue, def);
  108.     m -> mnext = mroot;
  109.     mroot = m;
  110.     DBUG_VOID_RETURN;
  111. }
  112.  
  113.  
  114. /*
  115.  * undefmac - undefine a macro.
  116.  * Return 0 if macro was successfully undefined, -1 if not found.
  117.  */
  118.  
  119. int undefmac (name)
  120. char *name;
  121. {
  122.     register MACRO *m = mroot;
  123.     register MACRO *prev = (MACRO *) NULL;
  124.     int result = -1;
  125.     extern void free ();
  126.  
  127.     DBUG_ENTER ("undefmac");
  128.     DBUG_3 ("mundef", "undefine macro '%s'", name);
  129.     while (m != (MACRO *) NULL && !STRSAME (name, m -> mname)) {
  130.     prev = m;
  131.     m = m -> mnext;
  132.     }
  133.     if (m != (MACRO *) NULL) {
  134.     result = 0;
  135.     if (prev == (MACRO *) NULL) {
  136.         mroot = m -> mnext;
  137.     } else {
  138.         prev -> mnext = m -> mnext;
  139.     }
  140.     free (m -> mname);
  141.     free (m -> mvalue);
  142.     free (m);
  143.     }
  144.     DBUG_RETURN (result);
  145. }
  146.  
  147.  
  148. /*
  149.  * Lookup a macro called 'name'.
  150.  * Return a pointer to its definition,
  151.  * or NULL if it does not exist.
  152.  */
  153.  
  154. char *gmacro (name)
  155. char *name;
  156. {
  157.     register MACRO *m;
  158.     register char *def = NULL;
  159.  
  160.     DBUG_ENTER ("gmacro");
  161.     DBUG_3 ("mname", "look up macro '%s'", name);
  162.     for (m = mroot; m != (MACRO *) NULL; m = m -> mnext) {
  163.     if (STRSAME (name, m -> mname)) {
  164.         def = m -> mvalue;
  165.         DBUG_3 ("mexp", "found expansion '%s'", def);
  166.         break;
  167.     }
  168.     }
  169.     DBUG_RETURN (def);
  170. }
  171.